
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JPA工作中有用到过吗？ - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>JPA工作中有用到过吗？ - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">JPA (Java Persistence API) 本身是一个具体的实现框架吗？它与 Hibernate 的关系是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JPA 本身不是一个具体的实现框架，而是一套由 Sun 公司为 POJO（普通Java对象）持久化提出的 Java 规范和 API 标准。Hibernate 则是一个实现了 JPA 规范的、功能强大的 ORM (对象关系映射) 框架。开发者通过 JPA 的标准接口进行编程，底层的具体实现可以是 Hibernate、EclipseLink 或 OpenJPA 等框架。</div>
          </div>
          <div class="card-source">来源: 一、简介 -> 1.1 JPA是什么？</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Spring Data JPA 相对于原生 JPA 的核心优势是什么？它是如何简化数据访问层开发的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring Data JPA 的核心优势在于它在 JPA 规范之上提供了更高层次的抽象，其核心理念是“约定大于配置”。它通过让开发者定义 Repository 接口（例如继承 JpaRepository），框架便会自动生成基本的 CRUD（增删改查）以及分页和排序等方法的实现，极大地减少了数据访问层的样板代码。</div>
          </div>
          <div class="card-source">来源: 一、简介 -> 1.2 Spring Data JPA是什么？</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在 Spring Data JPA 中，如何利用“方法命名查询”特性，在不写任何 JPQL 或 SQL 的情况下，实现根据用户名查找用户数据？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以通过在继承了 JpaRepository 的接口中，遵循特定的命名规则来定义方法。例如，要根据用户名查找用户，只需定义一个名为 `findByUsername(String username)` 的方法。Spring Data JPA 会自动解析这个方法名，并生成对应的 `WHERE username = ?` 查询语句，无需手动实现。</div>
          </div>
          <div class="card-source">来源: 三、核心概念与用法 -> 3.1 Repository查询方法 -> 方法命名查询 (Query Methods)</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">当“方法命名查询”无法满足复杂查询需求时，Spring Data JPA 提供了什么解决方案？请说明如何用它来执行原生 SQL 查询。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当方法命名查询不足以应对复杂场景时，可以使用 `@Query` 注解。要执行原生 SQL 查询，需要在 `@Query` 注解中编写 SQL 语句，并将其 `nativeQuery` 属性设置为 `true`。例如：`@Query(value = "SELECT * FROM user WHERE email = ?1", nativeQuery = true)`。</div>
          </div>
          <div class="card-source">来源: 三、核心概念与用法 -> 3.1 Repository查询方法 -> 使用 @Query 注解</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 SpringBoot 整合 JPA 时，如何通过配置文件控制 Hibernate 自动更新数据库表结构的行为？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">可以在 `application.properties` 或 `application.yml` 文件中，通过配置 `spring.jpa.hibernate.ddl-auto` 属性来控制。例如，将其值设置为 `update`，可以在应用启动时根据实体类的变化自动更新数据库表结构；设置为 `create` 则会每次启动都重新创建表。</div>
          </div>
          <div class="card-source">来源: 二、SpringBoot整合JPA -> 2.2 配置数据源</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在 JPA 中，`@Entity`、`@Table` 和 `@Id` 这三个核心注解分别起什么作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. `@Entity`：用于将一个 Java 类标记为 JPA 实体，表明它映射到数据库中的一张表。<br>2. `@Table`：用于指定实体类映射的数据库表的具体名称，如果省略，则默认使用类名作为表名。<br>3. `@Id`：用于标记实体类中的某个字段为表的主键。</div>
          </div>
          <div class="card-source">来源: 二、SpringBoot整合JPA -> 2.3 创建实体类</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">JPA 提供了哪些常见的主键生成策略？请列举并简要说明适用于 MySQL 和 Oracle 的策略。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JPA 通过 `@GeneratedValue` 注解的 `strategy` 属性来设置主键生成策略。常见的策略包括：<br>1. `IDENTITY`：依赖数据库的自增主键，适用于 MySQL 的 `AUTO_INCREMENT`。<br>2. `SEQUENCE`：使用数据库序列来生成主键，常用于 Oracle 数据库。<br>3. `TABLE`：使用一个特定的数据库表来保存和生成主键值。<br>4. `AUTO`：（默认值）由持久化提供商（如 Hibernate）自动选择合适的策略。</div>
          </div>
          <div class="card-source">来源: 四、主键生成策略</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在 Spring Data JPA 中，若要使用 `@Query` 注解执行一个更新（UPDATE）或删除（DELETE）操作，还需要额外添加哪两个注解？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">需要额外添加 `@Modifying` 和 `@Transactional` 注解。`@Modifying` 注解用于告知 Spring Data JPA 这不是一个查询操作，而是一个修改状态的操作。`@Transactional` 注解则用于确保该操作在事务中执行，保证数据的一致性和完整性。</div>
          </div>
          <div class="card-source">来源: 三、核心概念与用法 -> 3.2 @Transactional注解</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">在 SpringBoot 项目中整合 JPA 的基本步骤是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">整合 JPA 的基本步骤主要有四步：<br>1. **添加依赖**：在 `pom.xml` 中加入 `spring-boot-starter-data-jpa` 和数据库驱动（如 `mysql-connector-java`）的依赖。<br>2. **配置数据源**：在 `application.properties` 或 `yml` 文件中配置数据库连接信息和 JPA 相关属性。<br>3. **创建实体类**：创建带有 `@Entity` 等注解的 Java 类来映射数据库表。<br>4. **创建Repository接口**：创建一个接口并继承 `JpaRepository<T, ID>`，其中 `T` 是实体类类型，`ID` 是主键类型。</div>
          </div>
          <div class="card-source">来源: 二、SpringBoot整合JPA</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
